#include "SCalendar.h"

#include <core/StyleMgr.h>

#include <QColor>
#include <QLabel>
#include <QLayout>
#include <QMenu>
#include <QMouseEvent>
#include <QStylePainter>
#include <QTableView>
#include <QTextCharFormat>
#include <QToolButton>
#include <QToolTip>

SCalendar::SCalendar(QWidget* parent, bool showBorder, QString label,
                     int labelHeight)
    : QCalendarWidget(parent), m_showBorder(showBorder) {
  if (showBorder) {
    setContentsMargins(1, 1, 1, 1);
  }

  setWindowFlags(Qt::ToolTip | Qt::BypassGraphicsProxyWidget);
  this->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
  this->setDateEditEnabled(false);  // 取消通过键盘输入日期操作

  QTextCharFormat f = this->weekdayTextFormat(
      Qt::Monday);  // 获取周一字体格式,周六周日颜色需要特殊设置
  f.setForeground(
      QBrush(StyleMgr::instance().color("TextNormal")));  // 替换字体颜色
  QTextCharFormat weekdays = f;
  this->setWeekdayTextFormat(Qt::Sunday, weekdays);
  this->setWeekdayTextFormat(Qt::Saturday, weekdays);

  QString m_styleSheet =
      QString(
          "QToolButton#qt_calendar_monthbutton,#qt_calendar_yearbutton	"
          "{color: #%1;background-color: #%2;}"
          "QCalendarWidget QWidget#qt_calendar_navigationbar		"
          "		{background-color: #%2;}"
          "QCalendarWidget QAbstractItemView:enabled			"
          "			{color: #%1;background-color: "
          "#%2;selection-background-color: #%3;selection-color: #%4;outline: "
          "none;}"
          "QCalendarWidget QAbstractItemView::item:hover		"
          "			{background-color: #%3;}"
          "QCalendarWidget QTableView					"
          "				    {alternate-background-color: #%2;}"
          "QCalendarWidget QSpinBox#qt_calendar_yearedit		"
          "			"
          "{background:#%2;height:20px;width:30px;selection-background-color:#%"
          "2;color:#%4;}"
          "QCalendarWidget QSpinBox::up-button				"
          "			{subcontrol-origin: margin; "
          "subcontrol-position:top right; width:20px;}"
          "QCalendarWidget QSpinBox::down-button			"
          "				{subcontrol-origin: margin; "
          "subcontrol-position:bottom right; width:20px;}"
          "QCalendarWidget QToolButton::menu-indicator#qt_calendar_monthbutton "
          "{width:7px;subcontrol-position:right;subcontrol-origin:margin;}"
          "QToolButton#qt_calendar_prevmonth				"
          "				{icon-size:30px; "
          "qproperty-icon:url(:/widgets/image/calendar_month/"
          "calendar_month_left_normal.png);}"
          "QToolButton#qt_calendar_nextmonth				"
          "				{icon-size:30px; "
          "qproperty-icon:url(:/widgets/image/calendar_month/"
          "calendar_month_right_normal.png);}"
          "QToolButton#qt_calendar_prevmonth,#qt_calendar_nextmonth:"
          "hover	{background-color: #%2;}")
          .arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("Hover").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("Highlight").rgb(), 0, 16);

  setStyleSheet(m_styleSheet);
  //	for (auto each : this->findChildren<QTableView*>())
  //	{
  //		each->viewport()->installEventFilter(this);
  //	}

  if (!label.isEmpty()) {
    setFixedSize(width(), height() - labelHeight);

    QLabel* lb = new QLabel(label, this);
    lb->setWordWrap(true);
    lb->setStyleSheet(
        QString("QLabel {background-color: #%1; padding-left: 2px; "
                "padding-right: 2px;}}")
            .arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16));
    layout()->addWidget(lb);
  }

  installEventFilter(this);
}

SCalendar::~SCalendar() {}

void SCalendar::paintEvent(QPaintEvent* event) {
  QCalendarWidget::paintEvent(event);

  if (m_showBorder) {
    QStylePainter painter(this);
    painter.fillRect(rect(), StyleMgr::instance().color("TipsBorder"));
  }
}

void SCalendar::paintCell(QPainter* painter, const QRect& rect,
                          const QDate& date) const {
  QColor bgColor = StyleMgr::instance().color("BackNormal");
  QColor ndColor = StyleMgr::instance().color("SupportingWord");
  QColor dayColor = StyleMgr::instance().color("TextNormal");
  QColor tdColor = StyleMgr::instance().color("Green05");
  //	tdColor.setAlpha(200);

  painter->setPen(bgColor);

  selectedDate();
  QDate currentDay(QDate::currentDate());
  if (currentDay == date) {
    painter->setBrush(StyleMgr::instance().color("Hover"));
    painter->drawRect(rect);
  }

  if (date == _start && date != _end && this->monthShown() == date.month()) {
    painter->setBrush(QColor(19, 62, 56, 200));
    painter->drawRect(rect);
  } else if (date == _end && date == _start &&
             this->monthShown() == date.month() && date.isValid()) {
    painter->setBrush(StyleMgr::instance().color("TabBackNormal"));
    painter->drawRect(rect);
  } else if (date == _end && date != _start &&
             this->monthShown() == date.month()) {
    painter->setBrush(QColor(19, 62, 56, 200));
    painter->drawRect(rect);
  } else if (_colorStart.isValid() && _colorEnd.isValid() &&
             date <= _colorEnd && date >= _colorStart &&
             this->monthShown() == date.month()) {
    painter->setBrush(QColor(19, 62, 56, 200));
    painter->drawRect(rect);
  } else {
    QCalendarWidget::paintCell(painter, rect, date);
    return;
  }

  this->monthShown() == date.month() ? painter->setPen(dayColor)
                                     : painter->setPen(ndColor);

  if (date == _end && date == _start && this->monthShown() == date.month() &&
      date.isValid()) {
    painter->setPen(StyleMgr::instance().color("TabSelBorder"));
  }

  painter->drawText(rect, Qt::AlignHCenter | Qt::AlignVCenter,
                    QString::number(date.day()));
}

void SCalendar::setStart(const QDate& start) {
  _start = start;
  updateCells();
}

void SCalendar::setEnd(const QDate& end) {
  _end = end;
  updateCells();
}

void SCalendar::setSelectedColorBetweenTwoDatas(QDate start, QDate end) {
  _colorStart = start;
  _colorEnd = end;
  updateCells();
}

void SCalendar::active() {
  activateWindow();
  setWindowState(Qt::WindowActive);
}

bool SCalendar::eventFilter(QObject* obj, QEvent* event) {
  if (event->type() == QEvent::Wheel) {
    return true;
  } else if (event->type() == QEvent::WindowDeactivate) {
    hide();
  }

  return QCalendarWidget::eventFilter(obj, event);
}
